const axios = require('axios');

class TurtleTradingSystem {
    constructor(initialCapital = 100000) {
        this.initialCapital = initialCapital;
        this.capital = initialCapital;
        this.positions = new Map();
        this.trades = [];
        this.portfolio = [];
    }

    // 计算真实波动幅度均值 (ATR)
    calculateATR(data, period = 20) {
        const atr = [];
        
        for (let i = 0; i < data.length; i++) {
            if (i === 0) {
                atr.push(0);
                continue;
            }

            const high = data[i].high;
            const low = data[i].low;
            const prevClose = data[i - 1].close;

            const trueRange = Math.max(
                high - low,
                Math.abs(high - prevClose),
                Math.abs(low - prevClose)
            );

            if (i < period) {
                // 前period-1个值使用简单平均
                if (i === period - 1) {
                    const sum = data.slice(1, period + 1).reduce((acc, curr, idx) => {
                        const tr = Math.max(
                            curr.high - curr.low,
                            Math.abs(curr.high - data[idx].close),
                            Math.abs(curr.low - data[idx].close)
                        );
                        return acc + tr;
                    }, 0);
                    atr.push(sum / period);
                } else {
                    atr.push(trueRange);
                }
            } else {
                // 使用EMA计算ATR
                const prevATR = atr[i - 1];
                const currentATR = (prevATR * (period - 1) + trueRange) / period;
                atr.push(currentATR);
            }
        }

        return atr;
    }

    // 计算突破点
    calculateBreakouts(data) {
        const result = JSON.parse(JSON.stringify(data)); // 深拷贝数据

        for (let i = 0; i < data.length; i++) {
            // 20日突破点
            if (i >= 19) {
                const high20 = Math.max(...data.slice(i - 19, i + 1).map(d => d.high));
                const low20 = Math.min(...data.slice(i - 19, i + 1).map(d => d.low));
                result[i].high20 = high20;
                result[i].low20 = low20;
            } else {
                result[i].high20 = null;
                result[i].low20 = null;
            }

            // 55日突破点
            if (i >= 54) {
                const high55 = Math.max(...data.slice(i - 54, i + 1).map(d => d.high));
                const low55 = Math.min(...data.slice(i - 54, i + 1).map(d => d.low));
                result[i].high55 = high55;
                result[i].low55 = low55;
            } else {
                result[i].high55 = null;
                result[i].low55 = null;
            }

            // 退出突破点
            if (i >= 9) {
                const high10 = Math.max(...data.slice(i - 9, i + 1).map(d => d.high));
                const low10 = Math.min(...data.slice(i - 9, i + 1).map(d => d.low));
                result[i].high10 = high10;
                result[i].low10 = low10;
            } else {
                result[i].high10 = null;
                result[i].low10 = null;
            }

            if (i >= 19) {
                const high20Exit = Math.max(...data.slice(i - 19, i + 1).map(d => d.high));
                const low20Exit = Math.min(...data.slice(i - 19, i + 1).map(d => d.low));
                result[i].high20Exit = high20Exit;
                result[i].low20Exit = low20Exit;
            } else {
                result[i].high20Exit = null;
                result[i].low20Exit = null;
            }
        }

        return result;
    }

    // 计算头寸规模
    calculatePositionSize(price, atr, riskPerTrade = 0.01) {
        const dollarRisk = this.capital * riskPerTrade;
        const stopDistance = atr * 2; // 2倍ATR作为止损
        const positionSize = dollarRisk / stopDistance;
        return Math.floor(positionSize);
    }

    // 检查是否应该做多
    shouldEnterLong(data, currentIndex) {
        if (currentIndex < 55) return false;

        const current = data[currentIndex];
        const prev = data[currentIndex - 1];

        // 系统1 (20日突破) 或 系统2 (55日突破)
        return current.close > prev.high20 || current.close > prev.high55;
    }

    // 检查是否应该退出多头
    shouldExitLong(data, currentIndex, system = 1) {
        if (currentIndex < 20) return false;

        const current = data[currentIndex];
        const prev = data[currentIndex - 1];

        if (system === 1) {
            return current.close < prev.low10;
        } else {
            return current.close < prev.low20Exit;
        }
    }

    // 检查是否应该做空
    shouldEnterShort(data, currentIndex) {
        if (currentIndex < 55) return false;

        const current = data[currentIndex];
        const prev = data[currentIndex - 1];

        // 系统1 (20日突破) 或 系统2 (55日突破)
        return current.close < prev.low20 || current.close < prev.low55;
    }

    // 检查是否应该退出空头
    shouldExitShort(data, currentIndex, system = 1) {
        if (currentIndex < 20) return false;

        const current = data[currentIndex];
        const prev = data[currentIndex - 1];

        if (system === 1) {
            return current.close > prev.high10;
        } else {
            return current.close > prev.high20Exit;
        }
    }

    // 执行回测
    async backtest(symbol, startDate, endDate) {
        try {
            // 获取历史数据 (使用Alpha Vantage API示例)
            const data = await this.fetchHistoricalData(symbol, startDate, endDate);
            
            // 计算技术指标
            const atr = this.calculateATR(data);
            const enhancedData = this.calculateBreakouts(data);
            
            // 添加ATR到数据中
            enhancedData.forEach((item, index) => {
                item.atr = atr[index];
            });

            let cash = this.capital;
            let position = 0;
            let entryPrice = 0;
            let system = 1;

            for (let i = 55; i < enhancedData.length; i++) {
                const currentData = enhancedData[i];
                const currentPrice = currentData.close;
                const currentATR = currentData.atr;

                // 检查退出条件
                if (position > 0) { // 多头头寸
                    if (this.shouldExitLong(enhancedData, i, system)) {
                        // 平仓
                        cash += position * currentPrice;
                        
                        this.trades.push({
                            date: currentData.date,
                            action: 'SELL',
                            symbol: symbol,
                            price: currentPrice,
                            shares: position,
                            value: position * currentPrice,
                            system: system,
                            type: 'EXIT'
                        });
                        
                        position = 0;
                    }
                } else if (position < 0) { // 空头头寸
                    if (this.shouldExitShort(enhancedData, i, system)) {
                        // 平仓
                        cash += position * currentPrice;
                        
                        this.trades.push({
                            date: currentData.date,
                            action: 'COVER',
                            symbol: symbol,
                            price: currentPrice,
                            shares: Math.abs(position),
                            value: Math.abs(position) * currentPrice,
                            system: system,
                            type: 'EXIT'
                        });
                        
                        position = 0;
                    }
                }

                // 检查入场条件
                if (position === 0) {
                    const positionSize = this.calculatePositionSize(currentPrice, currentATR);

                    if (this.shouldEnterLong(enhancedData, i)) {
                        // 确定使用哪个系统
                        system = currentPrice > enhancedData[i-1].high20 ? 1 : 2;
                        
                        if (cash >= positionSize * currentPrice) {
                            position = positionSize;
                            cash -= position * currentPrice;
                            entryPrice = currentPrice;
                            
                            this.trades.push({
                                date: currentData.date,
                                action: 'BUY',
                                symbol: symbol,
                                price: currentPrice,
                                shares: position,
                                value: position * currentPrice,
                                system: system,
                                type: 'ENTRY'
                            });
                        }
                    } else if (this.shouldEnterShort(enhancedData, i)) {
                        // 确定使用哪个系统
                        system = currentPrice < enhancedData[i-1].low20 ? 1 : 2;
                        
                        if (cash >= positionSize * currentPrice) {
                            position = -positionSize;
                            cash -= position * currentPrice; // 做空获得现金
                            entryPrice = currentPrice;
                            
                            this.trades.push({
                                date: currentData.date,
                                action: 'SHORT',
                                symbol: symbol,
                                price: currentPrice,
                                shares: Math.abs(position),
                                value: Math.abs(position) * currentPrice,
                                system: system,
                                type: 'ENTRY'
                            });
                        }
                    }
                }

                // 更新每日投资组合价值
                const portfolioValue = cash + position * currentPrice;
                
                this.portfolio.push({
                    date: currentData.date,
                    cash: cash,
                    position: position,
                    positionValue: position * currentPrice,
                    totalValue: portfolioValue,
                    price: currentPrice
                });

                // 更新总资本
                this.capital = portfolioValue;
            }

            return {
                initialCapital: this.initialCapital,
                finalCapital: this.capital,
                totalReturn: ((this.capital - this.initialCapital) / this.initialCapital) * 100,
                trades: this.trades,
                portfolio: this.portfolio,
                data: enhancedData
            };

        } catch (error) {
            console.error('回测错误:', error);
            throw error;
        }
    }

    // 获取历史数据 (示例使用模拟数据)
    async fetchHistoricalData(symbol, startDate, endDate) {
        // 这里可以使用真实的API，如Alpha Vantage、Yahoo Finance等
        // 以下是模拟数据生成
        const data = [];
        let price = 100; // 初始价格
        
        const start = new Date(startDate);
        const end = new Date(endDate);
        const days = Math.floor((end - start) / (1000 * 60 * 60 * 24));
        
        for (let i = 0; i <= days; i++) {
            const date = new Date(start);
            date.setDate(start.getDate() + i);
            
            // 模拟价格波动
            const change = (Math.random() - 0.5) * 10;
            price = Math.max(1, price + change);
            
            const volatility = price * 0.02; // 2% 波动率
            
            data.push({
                date: date.toISOString().split('T')[0],
                open: price + (Math.random() - 0.5) * volatility,
                high: price + Math.random() * volatility,
                low: price - Math.random() * volatility,
                close: price,
                volume: Math.floor(Math.random() * 1000000) + 100000
            });
            
            price = data[data.length - 1].close;
        }
        
        return data;
    }

    // 生成回测报告
    generateReport(results) {
        const { initialCapital, finalCapital, totalReturn, trades } = results;
        
        const winningTrades = trades.filter(t => {
            if (t.type === 'EXIT') {
                const entryTrade = trades.find(et => 
                    et.symbol === t.symbol && 
                    et.type === 'ENTRY' && 
                    et.date < t.date
                );
                if (entryTrade) {
                    return (t.action === 'SELL' && t.price > entryTrade.price) ||
                           (t.action === 'COVER' && t.price < entryTrade.price);
                }
            }
            return false;
        });

        const winRate = trades.length > 0 ? (winningTrades.length / (trades.length / 2)) * 100 : 0;

        console.log('=== 海龟交易法则回测报告 ===');
        console.log(`初始资金: $${initialCapital.toLocaleString()}`);
        console.log(`最终资金: $${finalCapital.toLocaleString()}`);
        console.log(`总收益率: ${totalReturn.toFixed(2)}%`);
        console.log(`交易次数: ${trades.length}`);
        console.log(`胜率: ${winRate.toFixed(2)}%`);
        console.log(`最大回撤: ${this.calculateMaxDrawdown(results.portfolio).toFixed(2)}%`);
        
        return {
            initialCapital,
            finalCapital,
            totalReturn,
            totalTrades: trades.length,
            winRate,
            maxDrawdown: this.calculateMaxDrawdown(results.portfolio)
        };
    }

    // 计算最大回撤
    calculateMaxDrawdown(portfolio) {
        let peak = portfolio[0]?.totalValue || 0;
        let maxDrawdown = 0;

        for (const day of portfolio) {
            if (day.totalValue > peak) {
                peak = day.totalValue;
            }
            
            const drawdown = ((peak - day.totalValue) / peak) * 100;
            if (drawdown > maxDrawdown) {
                maxDrawdown = drawdown;
            }
        }

        return maxDrawdown;
    }
}

module.exports = TurtleTradingSystem;